/**
 * 错误处理工具类
 */

import type { AppError, DetailedError, ErrorSeverity } from '../types/errors'
import { ErrorType } from '../types/errors'

// 通知显示函数类型 (将由UI层实现)
type NotificationFunction = (message: string, type: 'success' | 'warning' | 'error' | 'info') => void

let showNotification: NotificationFunction = () => {}

// 设置通知函数
export function setNotificationHandler(handler: NotificationFunction) {
  showNotification = handler
}

// 错误处理器类
export class ErrorHandler {
  /**
   * 处理应用错误
   */
  static handle(error: AppError): void {
    // 记录错误日志
    console.error(`[${error.type}] ${error.message}`, error.details)
    
    // 显示用户友好的错误信息
    const userMessage = this.getUserFriendlyMessage(error.type)
    const notificationType = this.getNotificationType(error.type)
    
    showNotification(userMessage, notificationType)
  }

  /**
   * 创建应用错误
   */
  static createError(
    type: ErrorType,
    message: string,
    details?: any,
    recoverable: boolean = true
  ): AppError {
    return {
      type,
      message,
      details,
      timestamp: new Date(),
      recoverable
    }
  }

  /**
   * 创建详细错误
   */
  static createDetailedError(
    type: ErrorType,
    message: string,
    severity: ErrorSeverity,
    options: {
      details?: any
      context?: Record<string, any>
      userMessage?: string
      technicalMessage?: string
      suggestedAction?: string
      recoverable?: boolean
    } = {}
  ): DetailedError {
    return {
      type,
      message,
      severity,
      timestamp: new Date(),
      recoverable: options.recoverable ?? true,
      details: options.details,
      context: options.context,
      userMessage: options.userMessage,
      technicalMessage: options.technicalMessage,
      suggestedAction: options.suggestedAction
    }
  }

  /**
   * 获取用户友好的错误信息
   */
  private static getUserFriendlyMessage(errorType: ErrorType): string {
    const messages: Record<ErrorType, string> = {
      [ErrorType.FILE_NOT_FOUND]: '文件未找到',
      [ErrorType.PERMISSION_DENIED]: '权限不足，请检查文件访问权限',
      [ErrorType.INVALID_HISTORY_FORMAT]: '历史文件格式无效',
      [ErrorType.NETWORK_ERROR]: '网络连接错误',
      [ErrorType.DISK_SPACE_INSUFFICIENT]: '磁盘空间不足',
      [ErrorType.OPERATION_CANCELLED]: '操作已取消',
      [ErrorType.PARSING_ERROR]: '文件解析失败',
      [ErrorType.VALIDATION_ERROR]: '数据验证失败',
      [ErrorType.TIMEOUT_ERROR]: '操作超时',
      [ErrorType.SEARCH_ERROR]: '搜索失败',
      [ErrorType.INDEX_NOT_BUILT]: '索引未建立',
      [ErrorType.INDEX_BUILD_ERROR]: '索引建立失败',
      [ErrorType.OPERATION_IN_PROGRESS]: '操作正在进行中',
      [ErrorType.UNKNOWN_ERROR]: '未知错误，请重试'
    }

    return messages[errorType] || '操作失败，请重试'
  }

  /**
   * 获取通知类型
   */
  private static getNotificationType(errorType: ErrorType): 'success' | 'warning' | 'error' | 'info' {
    const warningTypes = [
      ErrorType.FILE_NOT_FOUND,
      ErrorType.OPERATION_CANCELLED
    ]

    const errorTypes = [
      ErrorType.PERMISSION_DENIED,
      ErrorType.INVALID_HISTORY_FORMAT,
      ErrorType.NETWORK_ERROR,
      ErrorType.DISK_SPACE_INSUFFICIENT,
      ErrorType.PARSING_ERROR,
      ErrorType.VALIDATION_ERROR,
      ErrorType.TIMEOUT_ERROR,
      ErrorType.UNKNOWN_ERROR
    ]

    if (warningTypes.includes(errorType)) {
      return 'warning'
    }

    if (errorTypes.includes(errorType)) {
      return 'error'
    }

    return 'info'
  }

  /**
   * 包装异步操作，自动处理错误
   */
  static async wrapAsync<T>(
    operation: () => Promise<T>,
    errorType: ErrorType,
    errorMessage: string
  ): Promise<T> {
    try {
      return await operation()
    } catch (error) {
      const appError = this.createError(
        errorType,
        errorMessage,
        error
      )
      this.handle(appError)
      throw appError
    }
  }

  /**
   * 验证必需参数
   */
  static validateRequired(value: any, fieldName: string): void {
    if (value === null || value === undefined || value === '') {
      throw this.createError(
        ErrorType.VALIDATION_ERROR,
        `${fieldName} 是必需的`,
        { field: fieldName, value }
      )
    }
  }

  /**
   * 验证文件路径
   */
  static validateFilePath(path: string): void {
    if (!path || typeof path !== 'string') {
      throw this.createError(
        ErrorType.VALIDATION_ERROR,
        '无效的文件路径',
        { path }
      )
    }

    // 检查路径遍历攻击
    if (path.includes('..') || path.includes('~')) {
      throw this.createError(
        ErrorType.VALIDATION_ERROR,
        '不安全的文件路径',
        { path }
      )
    }
  }
}